﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text.RegularExpressions;

namespace Unikado.PHPLibs.Tokenizer.Types
{

    /// <summary>
    /// A static helper class for converting a token text/code into a <see cref="TypeFine"/>, <see cref="TypeNormal"/>
    /// or <see cref="TypeRough"/> value.
    /// </summary>
    public static class TypeHelper
    {

        #region - - - - - -   P R I V A T E   F I E L D S   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

        private static readonly Dictionary<string, TypeFine> dataFine;
        private static readonly Dictionary<TypeFine, TypeNormal> fineToNormal;
        private static readonly Dictionary<TypeNormal, TypeRough> normalToRough;

        #endregion

        #region - - - - - -   I N T E R N A L   S T A T I C   F I E L D S   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

        internal static readonly string[] PhpFn03 = {
            "acos", "acosh", "addcslashes", "addslashes", "array_change_key_case", "array_chunk", "array_count_values", "array_diff_assoc", "array_fill","array_filter", "array_intersect_assoc", "array_map", "array_merge_recursive", "array_multisort", "array_push", "array_rand", "array_reduce","array_replace", "array_sum", "array_unshift", "asin","asinh", "atan", "atan2", "atanh","bcadd","bccomp", "bcdiv", "bcmod", "bcmul", "bcpow","bcpowmod", "bcscale", "bcsqrt","bcsub", "bindtextdomain", "bzclose","bzopen", "bzread", "bzwrite", "call_user_func", "call_user_func_array","call_user_method", "call_user_method_array", "checkdnsrr", "chgrp",    "chop", "chown", "chr", "chunk_split", "class_parents", "class_uses","clearstatcache", "closedir",  "connection_timeout", "cos", "cosh",  "count_chars", "curl_close", "curl_errno",  "curl_error", "curl_escape","curl_exec","curl_file_create", "curl_init", "curl_pause","curl_reset", "curl_setopt", "curl_setopt_array", "curl_strerror", "curl_unescape","curl_version",  "date_get_last_errors",  "date_isodate_set",  "date_sub",  "date_timestamp_get",  "date_timestamp_set", "date_timezone_get","date_timezone_set", "debug_backtrace", "decbin", "dechex", "dns_check_record",  "dns_get_mx", "dns_get_record", "doubleval", "ereg_replace","eregi_replace", "error_log", "error_reporting", "escapeshellarg", "escapeshellcmd", "exif_imagetype",  "exif_read_data", "extension_loaded","ezmlm_hash",  "fflush",  "fgetc",  "fgetcsv",  "fgetss",  "filegroup",  "fileinode",  "fileowner",  "fileperms",  "filetype", "finfo_close","finfo_file", "finfo_open", "fmod", "fnmatch", "fpassthru",  "fprintf",  "fputcsv",  "ftp_chdir",  "ftp_chmod",  "ftp_close",  "ftp_connect","ftp_delete",  "ftp_exec", "ftp_fget", "ftp_fput", "ftp_get", "ftp_get_option", "ftp_login", "ftp_mkdir", "ftp_nlist", "ftp_pasv", "ftp_put","ftp_pwd", "ftp_quit", "ftp_rename","ftp_rmdir","ftp_set_option", "ftp_site", "ftp_size", "ftp_ssl_connect", "func_get_arg", "func_get_args","func_num_args",  "gd_info", "get_class", "get_class_methods", "get_class_vars", "get_defined_functions", "get_defined_vars",  "get_headers","get_object_vars",  "get_parent_class",  "get_resource_type",  "gethostbyaddr",  "gethostbyname",   "gethostname",  "getimagesizefromstring","gettext",  "gettype", "gzclose", "gzcompress", "gzdecode", "gzdeflate", "gzencode", "gzfile", "gzopen", "gzread", "gzuncompress", "gzwrite","hash_copy", "hash_init", "headers_list","headers_sent", "htmlentities", "htmlspecialchars", "htmlspecialchars_decode", "http_response_code","iconv",  "iconv_get_encoding",  "iconv_mime_decode", "iconv_mime_decode_headers", "iconv_mime_encode", "iconv_set_encoding", "iconv_strlen","iconv_strpos","iconv_strrpos","iconv_substr","ignore_user_abort", "image_type_to_extension","image_type_to_mime_type", "imagealphablending","imageantialias",   "imagearc",   "imagechar",  "imagecolorallocatealpha",  "imagecolorat",   "imagecolorclosest",  "imagecolorclosestalpha","imagecolorexact", "imagecolorset",  "imagecolorstotal",  "imagecolortransparent", "imageconvolution",  "imagecopy", "imagecreatefromstring","imagecreatefromwebp",   "imagecrop",    "imagecropauto",   "imagedashedline",    "imageellipse",   "imagefilledarc",   "imagefilledellipse","imagefilledrectangle",  "imageflip",  "imagefontheight",  "imagefontwidth",  "imageftbbox",  "imagefttext",  "imagegif", "imageistruecolor","imagejpeg", "imageline","imageloadfont", "imagepolygon", "imagepsfreefont","imagepsloadfont", "imagepstext", "imagerectangle", "imagescale","imagesetinterpolation", "imagesetpixel", "imagestring", "imagetruecolortopalette", "imagettfbbox", "imagetypes", "imap_8bit", "imap_append","imap_base64","imap_body","imap_bodystruct","imap_check","imap_close","imap_create","imap_createmailbox","imap_delete", "imap_deletemailbox","imap_errors",   "imap_expunge",  "imap_fetch_overview",   "imap_fetchbody",  "imap_fetchheader",   "imap_fetchstructure",  "imap_fetchtext","imap_getmailboxes", "imap_header", "imap_headerinfo", "imap_headers", "imap_last_error",  "imap_list", "imap_listmailbox",  "imap_listscan","imap_listsubscribed", "imap_mail", "imap_mail_compose","imap_mail_copy", "imap_mail_move", "imap_mailboxmsginfo", "imap_mime_header_decode","imap_msgno", "imap_num_msg", "imap_num_recent", "imap_open", "imap_rename", "imap_renamemailbox", "imap_reopen","imap_rfc822_parse_adrlist","imap_rfc822_parse_headers",  "imap_rfc822_write_address",  "imap_savebody",  "imap_search",  "imap_sort",  "imap_status",  "imap_subscribe","imap_thread", "imap_undelete","imap_unsubscribe","imap_utf7_decode", "imap_utf7_encode","imap_utf8","ini_get","interface_exists", "ip2long","iptcembed",  "iptcparse", "is_a",  "is_callable", "is_finite",  "is_infinite", "is_long",  "is_nan", "is_real",  "is_resource", "is_scalar","is_subclass_of", "iterator_to_array", "json_decode", "json_encode", "json_last_error", "json_last_error_msg",  "lcfirst", "link", "long2ip","mb_convert_case", "mb_convert_encoding", "mb_detect_encoding", "mb_list_encodings","mb_parse_str", "mb_split", "mb_strcut", "mb_strimwidth","mb_stripos", "mb_stristr", "mb_strlen", "mb_strpos", "mb_strrchr", "mb_strrichr", "mb_strripos", "mb_strrpos", "mb_strstr", "mb_strtolower","mb_strtoupper", "mb_strwidth","mb_substr","mb_substr_count", "mcrypt_cbc", "mcrypt_cfb", "mcrypt_create_iv", "mcrypt_decrypt", "mcrypt_ecb","mcrypt_enc_get_block_size", "mcrypt_enc_get_iv_size",  "mcrypt_enc_get_key_size", "mcrypt_encrypt", "mcrypt_generic", "mcrypt_generic_init","mcrypt_get_block_size","mcrypt_get_iv_size","mcrypt_get_key_size", "mcrypt_module_close", "mcrypt_module_open", "md5_file", "method_exists","mhash", "mime_content_type", "money_format", "msql", "msql_affected_rows",  "msql_close", "msql_connect", "msql_create_db", "msql_createdb","msql_db_query",  "msql_error",  "msql_fetch_array",  "msql_fetch_field",  "msql_fetch_row",  "msql_num_rows",  "msql_numrows", "msql_query","msql_result",   "msql_select_db",  "mssql_bind",  "mssql_data_seek",  "mssql_fetch_field",  "mssql_fetch_object",  "mssql_get_last_message","mssql_guid_string", "mssql_next_result",  "mssql_num_fields", "mssql_pconnect",  "mssql_select_db", "mt_getrandmax", "mt_rand",  "mt_srand","mysql_client_encoding", "mysql_drop_db",  "mysql_info", "mysql_stat",  "mysql_unbuffered_query", "mysqli_bind_param",  "mysqli_bind_result","mysqli_client_encoding",   "mysqli_connect",   "mysqli_disable_rpl_parse",   "mysqli_enable_reads_from_master",   "mysqli_enable_rpl_parse","mysqli_escape_string",   "mysqli_execute",   "mysqli_fetch",    "mysqli_get_cache_stats",   "mysqli_get_metadata",    "mysqli_master_query","mysqli_param_count",  "mysqli_report",   "mysqli_rpl_parse_enabled",   "mysqli_rpl_probe",   "mysqli_send_long_data",  "mysqli_slave_query","number_format", "ob_clean", "ob_end_clean",  "ob_end_flush",  "ob_flush",  "ob_get_clean",  "ob_get_contents",  "ob_get_flush",  "ob_start","oci_cancel",   "oci_close",  "oci_commit",  "oci_connect",  "oci_error",  "oci_execute",  "oci_fetch",  "oci_fetch_all",  "oci_fetch_array","oci_fetch_assoc",  "oci_fetch_object",  "oci_fetch_row",  "oci_free_descriptor",  "oci_free_statement",  "oci_lob_copy",  "oci_new_connect","oci_new_cursor", "oci_num_rows", "oci_parse",  "oci_pconnect", "oci_result",  "oci_rollback", "openssl_cipher_iv_length", "openssl_decrypt","openssl_encrypt","openssl_free_key","openssl_open","openssl_seal","openssl_sign", "openssl_verify", "ord", "pack", "parse_str", "parse_url","password_get_info", "password_hash", "password_needs_rehash", "password_verify", "pg_affected_rows","pg_cancel_query", "pg_client_encoding","pg_convert","pg_dbname","pg_last_error", "pg_last_notice","pg_last_oid","pg_num_fields", "pg_options", "pg_parameter_status", "pg_pconnect","pg_result_error",  "pg_result_error_field", "pg_result_seek", "pg_result_status", "pg_set_client_encoding", "pg_trace", "pg_unescape_bytea","pg_version",  "php_check_syntax", "phpinfo",  "phpversion", "preg_filter",  "preg_grep", "preg_last_error",  "proc_get_status", "proc_nice","proc_terminate",  "property_exists",   "quoted_printable_decode",   "quoted_printable_encode",   "rand",   "rawurldecode",   "rawurlencode","read_exif_data", "readline_add_history","readline_clear_history","readline_list_history", "readline_read_history", "readline_write_history","register_shutdown_function",    "rewinddir",    "scandir",    "serialize",    "session_cache_expire",    "session_destroy",    "session_id","session_is_registered",  "session_name",  "session_regenerate_id",  "session_register",   "session_register_shutdown",  "session_save_path","set_error_handler",  "set_exception_handler", "set_socket_blocking",  "setlocale", "settype", "simplexml_import_dom", "simplexml_load_file","simplexml_load_string", "sin", "sinh", "sizeof", "sleep", "socket_accept", "socket_bind", "socket_close", "socket_connect", "socket_create","socket_get_option","socket_listen","socket_read","socket_select","socket_send", "socket_sendmsg", "socket_set_block", "socket_set_blocking","socket_set_nonblock", "socket_set_option", "socket_set_timeout", "socket_write","spl_autoload","spl_autoload_call","spl_autoload_functions","spl_object_hash",  "spliti",  "sqlite_array_query",  "sqlite_column",   "sqlite_create_function",  "sqlite_current",  "sqlite_error_string","sqlite_factory", "sqlite_has_prev", "sqlite_key",  "sqlite_last_error", "sqlite_num_fields", "sqlite_popen", "sqlite_prev", "sqlite_rewind","sqlite_seek",  "sqlite_single_query",  "sqlite_valid",  "sqlsrv_cancel", "sqlsrv_close", "sqlsrv_commit", "sqlsrv_connect", "sqlsrv_errors","sqlsrv_execute", "sqlsrv_fetch", "sqlsrv_fetch_array",  "sqlsrv_fetch_object",  "sqlsrv_free_stmt",  "sqlsrv_get_field",  "sqlsrv_has_rows","sqlsrv_num_rows", "sqlsrv_prepare", "sqlsrv_query","sqlsrv_rollback","sqrt", "srand", "sscanf", "str_ireplace", "str_pad", "str_word_count","strcasecmp","strchr","strcspn","stream_context_create","stream_context_get_default","stream_context_get_options","stream_context_get_params","stream_context_set_default",   "stream_context_set_option",    "stream_context_set_params",    "stream_copy_to_stream",   "stream_encoding","stream_get_contents",   "stream_get_line",    "stream_get_meta_data",    "stream_select",    "stream_set_blocking",    "stream_set_timeout","stream_set_write_buffer", "strip_tags", "stripos", "stripslashes", "stristr","strpbrk", "strrchr", "strrev", "strripos", "strspn", "strtok","strtr","substr_count","substr_replace","symlink","textdomain","tidy_error_count", "tidy_get_output","tidy_load_config", "tidy_set_encoding","time_sleep_until",   "timezone_abbreviations_list",   "timezone_identifiers_list",    "timezone_location_get",    "timezone_name_from_abbr","timezone_name_get", "timezone_offset_get", "timezone_open",  "timezone_transitions_get", "timezone_version_get", "trait_exists",  "ucfirst","ucwords", "uniqid","unpack", "unserialize","usleep", "var_dump","var_export", "version_compare","vfprintf","vprintf","vsprintf", "wordwrap", "zip_close","zip_open", "zip_read","class_implements", "class_parents", "class_uses", "iterator_apply", "iterator_count","iterator_to_array" };
        internal static readonly string[] PhpFn01 = {
            "abs","array_key_exists","array_keys","basename","chroot","count","date_create","date_format","date_parse","date_parse_from_format","defined","dir","dirname","empty","exec","explode","fclose","feof","fgets","file_exists","file_get_contents","file_put_contents","floor","fopen","fputs","fread","fwrite","getdate","glob","in_array","intval","is_array","is_dir","is_file","is_int","is_null","is_readable","is_string","is_writable","is_writeable","isset","join","list","mail","microtime","mkdir","mktime","mysql_close","mysql_connect","mysql_errno","mysql_error","mysql_escape_string","mysql_fetch_array","mysql_fetch_assoc","mysql_fetch_row","mysql_free_result","mysql_insert_id","mysql_num_rows","mysql_query","mysql_real_escape_string","mysql_result)","preg_match","preg_replace","preg_split","print","readfile","realpath","rename","rmdir","round","shell_exec","sprintf","stat","str_replace","strftime","strlen","strtolower","strtotime","strval","system","time","touch","trim","unlink" };
        internal static readonly string[] PhpFn02 = {
            "array_combine","array_diff","array_flip","array_intersect","array_merge","array_pad","array_pop","array_reverse","array_search","array_shift","array_slice","array_splice","array_unique","array_values","array_walk","array_walk_recursive","asort","arsort","base_convert","base64_decode","base64_encode","bindec","ceil","chdir","checkdate","chmod","class_exists","class_implements","constant","copy","date_add","date_create_from_format","date_date_set","date_default_timezone_get","date_default_timezone_set","date_diff","date_modify","date_offset_get","date_time_set","fileatime","filectime","filemtime","filesize","filter_has_var","filter_id","filter_input","filter_input_array","filter_list","filter_var","filter_var_array","floatval","flock","fscanf","fseek","fsockopen","fstat","ftell","ftruncate","function_exists","get_include_path","getcwd","getimagesize","getrandmax","gettimeofday","gmdate","gmmktime","gmstrftime","hash","hash_file","header","hexdec","html_entity_decode","imagecolorallocate","imagecopymerge","imagecopyresampled","imagecopyresized","imagecreate","imagecreatefromgif","imagecreatefromjpeg","imagecreatefrompng","imagecreatetruecolor","imagedestroy","imagefill","imagepng","imagerotate","imagesx","imagesy","imagettftext","implode","ini_set","is_bool","is_double","is_executable","is_float","is_integer","is_link","is_numeric","is_object","is_uploaded_file","ksort","krsort","localtime","ltrim","max","md5","min","move_uploaded_file","mssql_close","mssql_connect","mssql_execute","mssql_fetch_array","mssql_fetch_assoc","mssql_fetch_row","mssql_free_result","mssql_free_statement","mssql_init","mssql_num_rows","mssql_query","mssql_result","mssql_rows_affected","mysql_affected_rows","mysql_create_db","mysql_db_name","mysql_db_query","mysql_fetch_field","mysql_fetch_object","mysql_list_dbs","mysql_list_fields","mysql_list_tables","mysql_num_fields","mysql_pconnect","mysql_select_db","mysql_set_charset","mysql_tablename","natsort","natcasesort","nl2br","opendir","parse_ini_file","passthru","pathinfo","pclose","pg_close","pg_connect","pg_delete","pg_escape_bytea","pg_escape_identifier","pg_escape_literal","pg_escape_string","pg_execute","pg_fetch_all","pg_fetch_all_columns","pg_fetch_array","pg_fetch_assoc","pg_fetch_object","pg_fetch_result","pg_fetch_row","pg_free_result","pg_get_result","pg_insert","pg_num_rows","pg_prepare","pg_query","pg_query_params","pg_select","pg_send_execute","pg_send_prepare","pg_send_query","pg_send_query_params","pg_update","popen","preg_match_all","preg_quote","preg_replace_callback","print_r","print_f","proc_close","proc_open","range","readdir","readline","rewind","rsort","rtrim","session_start","set_include_path","sha1","sha1_file","sort","spl_autoload_register","split","sqlite_close","sqlite_escape_string","sqlite_exec","sqlite_fetch_all","sqlite_fetch_array","sqlite_fetch_object","sqlite_fetch_single","sqlite_fetch_string","sqlite_has_more","sqlite_next","sqlite_num_rows","sqlite_open","sqlite_query","str_repeat","strcmp","strpos","strptime","strrpos","strstr","strtoupper","substr","tempnam","tmpfile","usort","uaort","uksort","umask","unset","urldecode","urlencode" };
        internal static readonly string[] PhpClasses = {
            "__php_incomplete_class", "appenditerator", "arrayiterator", "arrayobject", "badfunctioncallexception", "badmethodcallexception", "cachingiterator", "callbackfilteriterator", "closure", "datetime", "dateinterval", "dateperiod", "directory", "directoryiterator", "domainexception", "generator", "emptyiterator", "errorexception", "exception", "filesystemiterator", "filteriterator", "globiterator", "infiniteiterator", "intldateformatter", "intlexception", "intliterator", "invalidargumentexception", "iteratoriterator", "lengthexception", "limititerator", "locale", "logicexception", "messageformatter", "multipleiterator", "mysqli", "mysqli_stmt", "mysqli_result", "mysqli_warning", "mysqli_sql_exception", "norewinditerator", "normalizer", "numberformatter", "outofboundsexception", "outofrangeexception", "overflowexception", "parentiterator", "pdo", "pdostatement", "pdoexception", "phar", "phardata", "pharexception", "php_user_filter", "rangeexception", "recursivearrayiterator", "recursivecachingiterator", "recursivecallbackfilteriterator", "recursivedirectoryiterator", "recursivefilteriterator", "recursiveiteratoriterator", "recursiveregexiterator", "recursivetreeiterator", "reflection", "reflectionclass", "reflectionfunction", "reflectionfunctionabstract", "reflectionmethod", "reflectionobject", "reflectionparameter", "reflectionproperty", "reflector", "reflectionexception", "regexiterator", "runtimeexception", "simplexmlelement", "simplexmliterator", "spldoublylinkedlist", "splfileinfo", "splfileobject", "splfixedarray", "splheap", "splmaxheap", "splminheap", "splobjectstorage", "splpriorityqueue", "splqueue", "splstack", "spltempfileobject", "sqlite3", "sqlite3stmt", "sqlite3result", "stdclass", "tidy", "underflowexception", "unexpectedvalueexception", "xmlreader", "xmlwriter", "ziparchive" };
        internal static readonly string[] PhpInterfaces = {
            "traversable", "iterator", "iteratoraggregate", "arrayaccess", "serializable", "countable", "outeriterator", "recursiveiterator", "seekableiterator", "splobserver", "splsubject" };
        
        #endregion

        #region - - - - - -   S T A T I C   C O N S T R U C T O R   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

        static TypeHelper()
        {
            #region dataFine
            dataFine = new Dictionary<string, TypeFine>
            {
                {" ", TypeFine.Space},                  {"\t", TypeFine.Tabulator},                 {"\n", TypeFine.NewLine},
                {"{", TypeFine.BlockOpenBracket},       {"(", TypeFine.ConditionOpenBracket},       {"[", TypeFine.SquareOpenBracket},
                {"}", TypeFine.BlockCloseBracket},      {")", TypeFine.ConditionCloseBracket},      {"]", TypeFine.SquareCloseBracket},
                {"public", TypeFine.Public},            {"protected", TypeFine.Protected},          {"private", TypeFine.Private},
                {"class", TypeFine.Class},              {"const", TypeFine.Const},                  {"define", TypeFine.Define},
                {"interface", TypeFine.Interface},      {"namespace", TypeFine.Namespace},          {"trait", TypeFine.Trait},
                {"function", TypeFine.Function},        {"use", TypeFine.Use},                      {"var", TypeFine.Var},
                {"extends", TypeFine.Extends},          {"implements", TypeFine.Implements},        {"abstract", TypeFine.Abstract},
                {"final", TypeFine.Final},              {"static", TypeFine.Static},                {"catch", TypeFine.Catch},
                {"finally", TypeFine.Finally},          {"throw", TypeFine.Throw},                  {"try", TypeFine.Try},
                {"echo", TypeFine.Echo},                {"print", TypeFine.Print},                  {"die", TypeFine.Die},
                {"exit", TypeFine.Exit},                {"var_dump", TypeFine.VarDump},             {"print_r", TypeFine.PrintR},
                {"true", TypeFine.True},                {"false", TypeFine.False},                  {"null", TypeFine.Null},
                {"array", TypeFine.Array},              {"eval", TypeFine.Eval},                    {"global", TypeFine.Global},
                {"for", TypeFine.Loop},                 {"foreach", TypeFine.Loop},                 {"while", TypeFine.Loop},
                {"do", TypeFine.Loop},                  {"if", TypeFine.IfElse},                    {"else", TypeFine.IfElse},
                {"elseif", TypeFine.IfElse},            {"switch", TypeFine.Switch},                {"case", TypeFine.Switch},
                {"goto", TypeFine.Goto},                {"declare", TypeFine.Declare},              {"as", TypeFine.As},
                {"break", TypeFine.Break},              {"continue", TypeFine.Continue},            {"default", TypeFine.Default},
                {"return", TypeFine.Return},            {"yield", TypeFine.Yield},                  {"endif", TypeFine.EndIf},
                {"endfor", TypeFine.EndFor},            {"endforeach", TypeFine.EndForeach},        {"endswitch", TypeFine.EndSwitch},
                {"enddeclare", TypeFine.EndDeclare},    {"__halt_compiler",TypeFine.KeywordsOther}, {"clone", TypeFine.Clone},
                {"callable", TypeFine.KeywordsOther},   {"empty", TypeFine.KeywordsOther},          {"instanceof", TypeFine.InstanceOf},
                {"insteadof", TypeFine.InsteadOf},      {"isset", TypeFine.KeywordsOther},          {"list", TypeFine.KeywordsOther},
                {"new", TypeFine.New},                  {"unset", TypeFine.KeywordsOther},          {"xor", TypeFine.BitwiseOperator},
                {"and", TypeFine.LogicalBoolean},       {"or", TypeFine.LogicalBoolean},            {"?", TypeFine.Questionmark},
                {"self", TypeFine.Self},                {"parent", TypeFine.Parent},
                {"$_COOKIE", TypeFine.Superglobal},     {"$_ENV", TypeFine.Superglobal},            {"$_FILES", TypeFine.Superglobal},
                {"$_GET", TypeFine.Superglobal},        {"$_POST", TypeFine.Superglobal},           {"$_REQUEST", TypeFine.Superglobal},
                {"$_SERVER", TypeFine.Superglobal},     {"$_SESSION", TypeFine.Superglobal},        {"$GLOBALS", TypeFine.Globals},
                {"$php_errormsg", TypeFine.VariablePredefined},                                     {"$HTTP_RAW_POST_DATA", TypeFine.VariablePredefined},
                {"$http_response_header", TypeFine.VariablePredefined},                             {"$argc", TypeFine.VariablePredefined},
                {"$argv", TypeFine.VariablePredefined}, {"__LINE__", TypeFine.MagicConstant},       {"__FILE__", TypeFine.MagicConstant},
                {"__DIR__", TypeFine.MagicConstant},    {"__FUNCTION__", TypeFine.MagicConstant},   {"__CLASS__", TypeFine.MagicConstant},
                {"__TRAIT__", TypeFine.MagicConstant},  {"__METHOD__", TypeFine.MagicConstant},     {"__NAMESPACE__", TypeFine.MagicConstant},
                {"include", TypeFine.Include},          {"include_once", TypeFine.IncludeOnce},     {"reuqire", TypeFine.Require},
                {"require_once", TypeFine.RequireOnce}
            };
            #endregion
            #region fineToNormal
            fineToNormal = new Dictionary<TypeFine, TypeNormal>
            {
                {TypeFine.None, TypeNormal.None}, {TypeFine.PhpTagOpen, TypeNormal.PhpTag},
                {TypeFine.PhpTagClose, TypeNormal.PhpTag}, {TypeFine.Space, TypeNormal.Space},
                {TypeFine.NewLine, TypeNormal.NewLine}, {TypeFine.HashComment, TypeNormal.Comment},
                {TypeFine.SlashComment, TypeNormal.Comment}, {TypeFine.MultilineComment, TypeNormal.Comment},
                {TypeFine.Docblock, TypeNormal.Docblock}, {TypeFine.Public, TypeNormal.Visibility},
                {TypeFine.Protected, TypeNormal.Visibility}, {TypeFine.Private, TypeNormal.Visibility},
                {TypeFine.Class, TypeNormal.SignatureIdentifier}, {TypeFine.Const, TypeNormal.SignatureIdentifier},
                {TypeFine.Define, TypeNormal.SignatureIdentifier}, {TypeFine.Interface, TypeNormal.SignatureIdentifier},
                {TypeFine.Namespace, TypeNormal.SignatureIdentifier}, {TypeFine.Trait, TypeNormal.SignatureIdentifier},
                {TypeFine.Function, TypeNormal.SignatureIdentifier}, {TypeFine.Use, TypeNormal.SignatureIdentifier},
                {TypeFine.Var, TypeNormal.SignatureIdentifier}, {TypeFine.Extends, TypeNormal.Inheritance},
                {TypeFine.Implements, TypeNormal.Inheritance}, {TypeFine.Abstract, TypeNormal.PrefixKeyword},
                {TypeFine.Final, TypeNormal.PrefixKeyword}, {TypeFine.Static, TypeNormal.PrefixKeyword},
                {TypeFine.Catch, TypeNormal.ExceptionHandling}, {TypeFine.Finally, TypeNormal.ExceptionHandling},
                {TypeFine.Throw, TypeNormal.ExceptionHandling}, {TypeFine.Try, TypeNormal.ExceptionHandling},
                {TypeFine.Echo, TypeNormal.Output}, {TypeFine.Print, TypeNormal.Output},
                {TypeFine.Die, TypeNormal.Exit}, {TypeFine.Exit, TypeNormal.Exit},
                {TypeFine.VarDump, TypeNormal.DebugOutput}, {TypeFine.PrintR, TypeNormal.DebugOutput},
                {TypeFine.True, TypeNormal.ValueKeyword}, {TypeFine.False, TypeNormal.ValueKeyword},
                {TypeFine.Array, TypeNormal.ValueKeyword}, {TypeFine.Null, TypeNormal.ValueKeyword},
                {TypeFine.Eval, TypeNormal.BadCodeKeyword}, {TypeFine.Global, TypeNormal.BadCodeKeyword},
                {TypeFine.Loop, TypeNormal.ControlStructure}, {TypeFine.IfElse, TypeNormal.ControlStructure},
                {TypeFine.Switch, TypeNormal.ControlStructure}, {TypeFine.Goto, TypeNormal.ControlStructure},
                {TypeFine.Declare, TypeNormal.ControlStructure}, {TypeFine.Return, TypeNormal.ControlStructureInternal},
                {TypeFine.As, TypeNormal.ControlStructureInternal}, {TypeFine.Break, TypeNormal.ControlStructureInternal},
                {TypeFine.Continue, TypeNormal.ControlStructureInternal}, {TypeFine.Default, TypeNormal.ControlStructureInternal},
                {TypeFine.Yield, TypeNormal.ControlStructureInternal}, {TypeFine.EndIf, TypeNormal.ControlStructureAlt},
                {TypeFine.EndFor, TypeNormal.ControlStructureAlt}, {TypeFine.EndForeach, TypeNormal.ControlStructureAlt},
                {TypeFine.EndSwitch, TypeNormal.ControlStructureAlt}, {TypeFine.EndDeclare, TypeNormal.ControlStructureAlt},
                {TypeFine.Self, TypeNormal.SpecialClasses}, {TypeFine.ClassStatic, TypeNormal.SpecialClasses},
                {TypeFine.Parent, TypeNormal.SpecialClasses}, {TypeFine.Clone, TypeNormal.OtherKeyword},
                {TypeFine.InstanceOf, TypeNormal.OtherKeyword}, {TypeFine.InsteadOf, TypeNormal.OtherKeyword},
                {TypeFine.New, TypeNormal.OtherKeyword}, {TypeFine.KeywordsOther, TypeNormal.OtherKeyword},
                {TypeFine.EqualTypesafe, TypeNormal.ComparisonOperator}, {TypeFine.Equal, TypeNormal.ComparisonOperator},
                {TypeFine.EqualNumerical, TypeNormal.ComparisonOperator}, {TypeFine.StringConcat, TypeNormal.AssignmentOperator},
                {TypeFine.AssignBitwise, TypeNormal.AssignmentOperator}, {TypeFine.AssignAritmethic, TypeNormal.AssignmentOperator},
                {TypeFine.AssignArray, TypeNormal.AssignmentOperator}, {TypeFine.Assign, TypeNormal.AssignmentOperator},
                {TypeFine.ScopeInstanceOperator, TypeNormal.ScopeOperator}, {TypeFine.ScopeStaticOperator, TypeNormal.ScopeOperator},
                {TypeFine.BitwiseShift, TypeNormal.BitwiseOperator}, {TypeFine.BitwiseOperator, TypeNormal.BitwiseOperator},
                {TypeFine.Increment, TypeNormal.XCrementOperator}, {TypeFine.Decrement, TypeNormal.XCrementOperator},
                {TypeFine.LogicalBoolean, TypeNormal.LogicalOperator}, {TypeFine.Questionmark, TypeNormal.LogicalOperator},
                {TypeFine.Colon, TypeNormal.LogicalOperator}, {TypeFine.AritmethicOperator, TypeNormal.AritmethicOperator},
                {TypeFine.Semicolon, TypeNormal.OtherOperator}, {TypeFine.Comma, TypeNormal.OtherOperator},
                {TypeFine.ErrorControl, TypeNormal.OtherOperator}, {TypeFine.Command, TypeNormal.Command},
                {TypeFine.StringSingle, TypeNormal.String}, {TypeFine.StringDouble, TypeNormal.String},
                {TypeFine.HereDoc, TypeNormal.HereNowDoc}, {TypeFine.NowDoc, TypeNormal.HereNowDoc},
                {TypeFine.Superglobal, TypeNormal.VariablePredefined}, {TypeFine.Globals, TypeNormal.VariablePredefined},
                {TypeFine.VariablePredefined, TypeNormal.VariablePredefined}, {TypeFine.MagicConstant, TypeNormal.ConstantPredefined},
                {TypeFine.PhpFunctionName, TypeNormal.OtherPredefined}, {TypeFine.PhpInterfaceName, TypeNormal.OtherPredefined},
                {TypeFine.PhpClassName, TypeNormal.OtherPredefined}, {TypeFine.BlockOpenBracket, TypeNormal.OpenBracket},
                {TypeFine.ConditionOpenBracket, TypeNormal.OpenBracket}, {TypeFine.SquareOpenBracket, TypeNormal.OpenBracket},
                {TypeFine.BlockCloseBracket, TypeNormal.CloseBracket}, {TypeFine.ConditionCloseBracket, TypeNormal.CloseBracket},
                {TypeFine.SquareCloseBracket, TypeNormal.CloseBracket}, {TypeFine.Include, TypeNormal.Include},
                {TypeFine.IncludeOnce, TypeNormal.Include}, {TypeFine.Require, TypeNormal.Require},
                {TypeFine.RequireOnce, TypeNormal.Require}, {TypeFine.Float, TypeNormal.Float},
                {TypeFine.FloatExp, TypeNormal.Float}, {TypeFine.Integer, TypeNormal.Integer},
                {TypeFine.IntegerBin, TypeNormal.Integer}, {TypeFine.IntegerHex, TypeNormal.Integer},
                {TypeFine.IntegerOct, TypeNormal.Integer}, {TypeFine.Variable, TypeNormal.Variable},
                {TypeFine.VariableExtend, TypeNormal.Variable}, {TypeFine.Word, TypeNormal.Word},
                {TypeFine.Other, TypeNormal.Other}
            };
            #endregion
            #region normalToRough
            normalToRough = new Dictionary<TypeNormal, TypeRough>
            {
                {TypeNormal.None, TypeRough.None}, {TypeNormal.PhpTag, TypeRough.PhpTag},
                {TypeNormal.Space, TypeRough.Whitespace}, {TypeNormal.NewLine, TypeRough.Whitespace},
                {TypeNormal.Comment, TypeRough.Comment}, {TypeNormal.Docblock, TypeRough.Comment},
                {TypeNormal.Visibility, TypeRough.KeywordSignature}, {TypeNormal.SignatureIdentifier, TypeRough.KeywordSignature},
                {TypeNormal.Inheritance, TypeRough.KeywordSignature}, {TypeNormal.PrefixKeyword, TypeRough.KeywordSignature},
                {TypeNormal.ExceptionHandling, TypeRough.Keyword}, {TypeNormal.Output, TypeRough.Keyword},
                {TypeNormal.Exit, TypeRough.Keyword}, {TypeNormal.DebugOutput, TypeRough.Keyword},
                {TypeNormal.ValueKeyword, TypeRough.Keyword}, {TypeNormal.BadCodeKeyword, TypeRough.Keyword},
                {TypeNormal.ControlStructure, TypeRough.Keyword}, {TypeNormal.ControlStructureInternal, TypeRough.Keyword},
                {TypeNormal.ControlStructureAlt, TypeRough.Keyword}, {TypeNormal.SpecialClasses, TypeRough.Keyword},
                {TypeNormal.OtherKeyword, TypeRough.Keyword}, {TypeNormal.ComparisonOperator, TypeRough.Operator},
                {TypeNormal.AssignmentOperator, TypeRough.Operator}, {TypeNormal.ScopeOperator, TypeRough.Operator},
                {TypeNormal.BitwiseOperator, TypeRough.Operator}, {TypeNormal.XCrementOperator, TypeRough.Operator},
                {TypeNormal.LogicalOperator, TypeRough.Operator}, {TypeNormal.AritmethicOperator, TypeRough.Operator},
                {TypeNormal.OtherOperator, TypeRough.Operator}, {TypeNormal.String, TypeRough.String},
                {TypeNormal.HereNowDoc, TypeRough.String}, {TypeNormal.Command, TypeRough.String},
                {TypeNormal.VariablePredefined, TypeRough.Predefined}, {TypeNormal.ConstantPredefined, TypeRough.Predefined},
                {TypeNormal.OtherPredefined, TypeRough.Predefined}, {TypeNormal.OpenBracket, TypeRough.Bracket},
                {TypeNormal.CloseBracket, TypeRough.Bracket}, {TypeNormal.Include, TypeRough.Include},
                {TypeNormal.Require, TypeRough.Include}, {TypeNormal.Float, TypeRough.Number},
                {TypeNormal.Integer, TypeRough.Number}, {TypeNormal.Variable, TypeRough.Other},
                {TypeNormal.Word, TypeRough.Other}, {TypeNormal.Other, TypeRough.Other}
            };
            #endregion
        }

        #endregion

        #region - - - - - -   P U B L I C   S T A T I C   M E T H O D S   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

        /// <summary>
        /// Converts a token text/code to a <see cref="TypeFine"/> (returned by <paramref name="typeFine"/>)
        /// and returns if conversion was successfull.
        /// </summary>
        /// <param name="tokenString">The token string</param>
        /// <param name="isWord">Is token string a word?</param>
        /// <param name="typeFine">Returns the resulting <see cref="TypeFine"/> if Method returns <c>true</c></param>
        /// <param name="isDeclaration">…</param>
        /// <returns>bool</returns>
        public static bool ConvertToFine(string tokenString, bool isWord, out TypeFine typeFine, bool isDeclaration = false)
        {
            typeFine = TypeFine.None;
            string str = tokenString.TrimStart('\\');
            string strLower = str.ToLowerInvariant();
            //if ("\\in_array" == strLower) Debug.WriteLine("==> \\in_array");
            //if ("in_array" == strLower) Debug.WriteLine("==> in_array");
            if (dataFine.ContainsKey(str))
            {
                typeFine = dataFine[str];
                return true;
            }
            if (dataFine.ContainsKey(strLower))
            {
                typeFine = dataFine[strLower];
                return true;
            }
            if (!isDeclaration)
            {
                if (Array.IndexOf(PhpFn01, strLower) > -1)
                {
                    typeFine = TypeFine.PhpFunctionName;
                    return true;
                }
                if (Array.IndexOf(PhpFn02, strLower) > -1)
                {
                    // TODO matches to many things

                    typeFine = TypeFine.PhpFunctionName;
                    return true;
                }
                if (Array.IndexOf(PhpFn03, strLower) > -1)
                {
                    typeFine = TypeFine.PhpFunctionName;
                    return true;
                }
                if (Array.IndexOf(PhpInterfaces, strLower) > -1)
                {
                    typeFine = TypeFine.PhpInterfaceName;
                    return true;
                }
                if (Array.IndexOf(PhpClasses, strLower) > -1)
                {
                    typeFine = TypeFine.PhpClassName;
                    return true;
                }
            }
            if (isWord)
            {
                typeFine = TypeFine.Word;
                return true;
            }
            return false;
        }
        /// <summary>
        /// Converts a <see cref="TypeFine"/> to a  a <see cref="TypeNormal"/>.
        /// </summary>
        /// <param name="typeFine">The fine type to convert.</param>
        /// <returns>TypeNormal</returns>
        public static TypeNormal ConvertFineToNormal(TypeFine typeFine)
        {
            return fineToNormal[typeFine];
        }
        /// <summary>
        /// Converts a <see cref="TypeNormal"/> to a  a <see cref="TypeRough"/>.
        /// </summary>
        /// <param name="typeNormal">The fine type to convert.</param>
        /// <returns>TypeRough</returns>
        public static TypeRough ConvertNormalToRough(TypeNormal typeNormal)
        {
            return normalToRough[typeNormal];
        }

        #endregion

    }

}